package cn.caplike.demo.repository.design.pattern.singleton;

import java.util.ArrayList;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

public class SingletonHolder {

    @SuppressWarnings("rawtypes")
    private static final ConcurrentMap<Class, Singleton> map = new ConcurrentHashMap<>();

    @SuppressWarnings("unchecked")
    public static <E> Singleton<E> getSingleton(Class<E> type) {
        Singleton<E> s = map.get(type);
        if (s == null) {
            synchronized (map) {
                if ((s = map.get(type)) == null)
                    map.put(type, s = new Singleton<>());
            }
        }
        return s;
    }

    public static void main(String[] args) {
        Singleton<String> single = SingletonHolder.getSingleton(String.class);
        single.add("123");
        single.add("456");
        System.out.println(single.get(0));
        Singleton<Integer> single1 = SingletonHolder.getSingleton(Integer.class);
        single1.add(1);
        single1.add(2);
        System.out.println(single1.get(0));

        Singleton<String> single2 = SingletonHolder.getSingleton(String.class);
        single2.add("aa");
        single2.add("bb");
        System.out.println(single2.get(3));
    }

    public static class Singleton<E> {
        ArrayList<E> list = new ArrayList<>();

        private Singleton() {
        }

        @SuppressWarnings("unchecked")
        public E getData() {
            return (E) "123";
        }

        public boolean add(E e) {
            return list.add(e);
        }

        public E get(int index) {
            return list.get(index);
        }
    }
}